package Triangulation;

import java.util.List;

import controller.Notification;
import controller.NotificationCenter;
import tools.FastLMTSkeletonCreator;
import Triangulation.minimalityMetrics.MinimalityMetric;
import datatypes.Edge;
import datatypes.IndexedFaceSet;
import datatypes.Vertex;

/**
 * 
 * @author markessien, nils
 *
 */
public class FastLMTTriangulator implements LMTTriangulator
{
	FastLMTSkeletonCreator lmtSkeletonCreator = null;
	
	public FastLMTTriangulator () {
	}
	
	@Override
	public List<Edge> processVertices(Vertex[] vertices, MinimalityMetric metric, boolean triangulatePolygons)
	{
		this.lmtSkeletonCreator = new FastLMTSkeletonCreator(metric);
		long startSet = System.currentTimeMillis();
		Vertex[] verticesClone = new Vertex[vertices.length];
		for (int i = 0; i < vertices.length; i++) {
			verticesClone[i] = vertices[i].clone();
		}
		IndexedFaceSet set = new IndexedFaceSet(true, verticesClone);
		double timeGenerateSet = ((double)(System.currentTimeMillis() - startSet))/1000;
		
		System.out.println("Running time adding vertices to set: " + timeGenerateSet);
		
		// Calculate the LMT
		lmtSkeletonCreator.calculateLMT(set);
		
		// now you can get the edges of the LMT from the set's edgesIn list.
		
		// n.b.: set.getCandidateEdges() will return a list of all locally minimal edges
		// that are left over, i.e. those edges are only within the holes to fill.
		// You may want to use those to quickly identify the vertices forming the holes.
		
		
		if (triangulatePolygons) {
			//fill the holes!
			new PolygonTriangulator().triangulateLMTHoles(set, metric);
		}
		
		// just for grins, showing edges failing diamond test:
//		for (Edge edge : set.edgesFailedDiamondTest) {
//			set.edgesIn.add(edge);
//		}
		
		// just for grins, showing edges leftover candidate edges:
		if (set.getCandidateEdges().size() > 3) {
			for (Edge edge : set.getCandidateEdges()) {
				set.edgesIn.add(edge);
			}	//produces infinite loop with 3 vertices!
		}
		
		
		NotificationCenter nc = NotificationCenter.defaultNotificationCenter();
		nc.postNotification(Notification.didFinishMWT, set.edgesIn);
		return set.edgesIn;
	}

	
	@Override
	public String getName()
	{
		return "LMT";
	}
	
	public FastLMTSkeletonCreator getSkeletonCreator() {
		return lmtSkeletonCreator;
	}

	@Override
	public List<Edge> processVertices(Vertex[] points, MinimalityMetric metric) {
		return processVertices(points, metric, true);
	}
		
}